home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 126-150 / disk_138 / amigaline / amigaline7 < prev    next >
Text File  |  1992-05-06  |  8KB  |  259 lines

  1.             Technical Note #7
  2.         How to deal with large stack needs
  3.  
  4. SUMMARY
  5.  
  6.  
  7. $ 7/4 How to deal with large stack needs
  8.     ^ Special note: This replaces tech note #4.  Please delete #4.
  9. $ release
  10. $ 11-Jan-87 Bryce Nesbitt / TVD
  11. $ stack size, Workbench, CLI, process, startups, SetStack(), 68000
  12.  
  13.     This note is all about what to do if there is a chance your program
  14. might require more than 4000 bytes of stack.
  15.  
  16. ----------------------------------------------------------------------------
  17.  
  18.     If your program needs more than the 4000 byte default stack, it has
  19.     some work to do.  It will need to check if the stack it is running on.
  20.     If the stack is too small it must take one of two actions:
  21.  
  22.     1.    Abort with an error requester.
  23.     2.    Allocate enough space and use SetStack() to point to it.  Source
  24.     for SetStack() is included.
  25.  
  26.     If there is any chance at all that user input may cause your
  27.     program to use more stack than normal, it is vital that you leave the
  28.     stack checking option of your compiler enabled.  Recursive functions
  29.     are particularly notorious stack blowers.
  30.  
  31.  
  32. WORKBENCH
  33.  
  34.     When stared from the Workbench tool, your stack size might have
  35.     come from one of three places:
  36.  
  37.     1.    The stack field of any random Project icon.
  38.     2.    The stack field in your Tool's icon.
  39.     3.    The Workbench's default stack size.
  40.  
  41.     The icon that started you tool decides the stack size.    If the
  42.     stack field of that icon is blank, then the default of ~4000 bytes is
  43.     used.
  44.  
  45.        If the user sets the stack size to an odd number then the Workbench
  46.     tool will crash, so don't worry about that situation.
  47.  
  48.  
  49. CLI
  50.  
  51.     When your code is started up it does NOT get a new process
  52.     invocation; as "CLI 3" your code is literally the same process that
  53.     runs CLI task 3.  This is the reason for the warnings about restoring
  54.     the environment back just the way it was before launch.
  55.  
  56.     When the CLI starts a program it does create one thing anew; the
  57.     stack.  This is not the same stack the CLI itself uses.  The size of
  58.     this stack is *not* recorded in the normal "task" structure.  It must
  59.     be extracted from the top of the running stack.  See the examples.
  60.  
  61.  
  62. ----------------------------- C EXAMPLE ------------------------------------
  63. #include "libraries/dosextens.h"
  64. char *malloc();
  65. struct Process *FindTask();
  66.  
  67. void main()
  68. {
  69. ULONG  stacksize;
  70. struct Process *Process;
  71. char   *mem;
  72.  
  73.     /* The stack size is the long pointed to by pr_ReturnAddr */
  74.     Process=FindTask(0L);
  75.     stacksize=*((ULONG *)Process->pr_ReturnAddr);
  76.     printf("Stack size is %ld\n",stacksize);
  77.  
  78.     if (!( mem=malloc(8192) ))
  79.     exit(20);
  80.     SetStack(mem,8192L);
  81.  
  82.     stacksize=*((ULONG *)Process->pr_ReturnAddr);
  83.     printf("Stack size is %ld\n",stacksize);
  84.     Delay(80L);
  85. }
  86.  
  87. ;---------------------------------------------------------------------------
  88. ;NAME
  89. ;    SetStack -- use a different process stack
  90. ;    V1.0 Tuesday 19-Jan-88 04:14:15 By Bryce Nesbitt
  91. ;
  92. ;SYNOPSIS
  93. ;    SetStack(newstack,size)
  94. ;          a1       d0
  95. ;
  96. ;    char *newstack;
  97. ;    long size;
  98. ;
  99. ;FUNCTION
  100. ;    This function points the current process' stack to a new memory
  101. ;    location.    The active part of the old stack is duplicated, so no
  102. ;    context is lost.  SetStack() also tickles the proper fields in the task
  103. ;    structure to tell the system about the change.  At this time it does
  104. ;    not deallocate the old stack.
  105. ;
  106. ;USAGE
  107. ;    Typically this is used by a process that needs a larger stack than it
  108. ;    might have been started with.  The stack size can be found with:
  109. ;
  110. ;    #include "libraries/dosextens.h"
  111. ;    ...
  112. ;    stack=*(ULONG *)( ((struct Process *)FindTask(0L))->pr_ReturnAddr );
  113. ;
  114. ;    Or in English, the long word at the address pointed to by pr_ReturnAddr.
  115. ;
  116. ;WARNINGS
  117. ;    A future revision of exec may do stack blowout checking every time a
  118. ;    process/task is switched out.  This protective feature will not be
  119. ;    available to programs that use funky methods of swapping stacks.
  120. ;
  121. ;    This only works for processes, tasks are not eligible.
  122. ;
  123. ;    Don't skimp on stack... you'll get burned.  Any call to the dos.library,
  124. ;    for example, takes just under 1600 bytes *minimum*.
  125. ;
  126. ;INPUTS
  127. ;    newstack - Pointer to memory block for stack.  Must be longword aligned.
  128. ;    size -    The size of the block.    Must be an even multiple of 4 bytes.
  129. ;
  130. ;SEE ALSO
  131. ;    AddTask()
  132.  
  133. newtop        equr a0 ;Bind names to registers
  134. newbottom    equr a1 ;Search & replace to assemble
  135. retaddr     equr a2 ;Under Lattice V4.0
  136. temp1        equr a3
  137. temp2        equr a4
  138. newsize     equr d0
  139. oldsize     equr d1
  140. oldtop        equr d2
  141. ;
  142. ;SetStack()
  143. ;V1.0 Tuesday 19-Jan-88 04:14:15 (C)1988 Bryce Nesbitt
  144. ;1712 Marin Ave.  Berkeley, Ca  94707-2206 415-524-2110
  145. ;ucbvax!hoser!bryce  -or-  bryce@hoser.berkeley.EDU
  146. ;
  147. ;Structure of stack:
  148. ;
  149. ;     -------
  150. ;     -4 size
  151. ;     -8 finalRTS
  152. ;      ...
  153. ;     -size blowoutdata     ;For checking stack blowouts
  154.  
  155.         XDEF    _SetStack
  156.         XDEF    SetStack
  157. _SetStack    move.l    4(a7),a1
  158.         move.l    8(a7),d0
  159. SetStack    movem.l d2/a2-a4/a6,-(a7)
  160.  
  161.         move.l    newsize,newtop
  162.         adda.l    newbottom,newtop    ;newbottom+size=newtop
  163.  
  164.         move.l    4,a6            ;exec library
  165.         move.l    $114(a6),temp1      ;Internal "magic";FindTask(0L);
  166.         lea.l    $b0(temp1),retaddr  ;&pr_ReturnAddr
  167.  
  168.         move.l    (retaddr),temp1     ;Get pr_ReturnAddr
  169.         move.l    (temp1)+,oldsize    ;Get old stack size. temp1+...
  170.         move.l    temp1,oldtop        ;...now points to old stack top
  171.         move.l    newtop,temp2
  172. copystack    move.w    -(temp1),-(temp2)
  173.         cmp.l    temp1,a7
  174.         bne.s    copystack
  175.  
  176.         move.l    newsize,-4(newtop)  ;Set new stack size value
  177.         move.l    oldtop,temp1
  178.         sub.l    oldsize,temp1
  179.         move.l    (temp1),(newbottom) ;Copy bottom long
  180.  
  181.         addq.b    #1,$127(a6)         ;Internal "magic"
  182.          move.l  newtop,(retaddr)
  183.          subq.l  #4,(retaddr)       ;pr_ReturnAddr is 4 under top...
  184.          sub.l     a7,oldtop        ;Get old stack offset
  185.          sub.l     oldtop,newtop        ;index into new stack
  186.          move.l  newtop,a7
  187.         jsr    -$138(a6)           ;Public Permit();
  188.  
  189.         movem.l (a7)+,d2/a2-a4/a6
  190.         rts
  191.         END
  192.  
  193.  
  194. -------------UUENCODED OBJECT FILE (See Fish #53 for decoder)----------------
  195.  
  196. begin 644 SetStack.o
  197. M```#YP````````/I````$R)O``0@+P`(2.<@.B!`T<DL>``$)FX!%$7K`+`FO
  198. M4B(;)`LH2#DCO\MF^B%`__PF0I?!(I-2+@$G)(A9DI2/D<(N2$ZN_LA,WUP$]
  199. M3G4```/O`0```E-E=%-T86-K````"`$```-?4V5T4W1A8VL`````````````G
  200. %`````_+OD
  201. ``
  202. end
  203. size 140
  204.  
  205. ;------------------ ASSEMBLY STARTUP MODULE W/STACK CHECK ------------------
  206. ;
  207. ; 25-Jan-87  Bryce Nesbitt
  208. ;
  209. ; A complete startup module for assembly language programs.  Works from
  210. ; Workbench or CLI.
  211. ;
  212.     NOLIST
  213.     INCLUDE "exec/types.i"
  214.     INCLUDE "libraries/dosextens.i"
  215.     LIST
  216. jsrlib    MACRO
  217.     xref _LVO\1
  218.     jsr  _LVO\1(a6)
  219.     ENDM
  220. ;
  221. ; On startup (A7) contains a return address,
  222. ; 4(A7) contains the size of the stack in bytes
  223. ;
  224.         move.l    4(a7),d7            ;--Get CLI stack size--
  225.         move.l    4,a6            ;Get exec library pointer
  226.         suba.l    a1,a1            ;Put zero in A1
  227.         jsrlib    FindTask        ;Find this task
  228.         move.l    d0,a5
  229.         moveq    #0,d0            ;Set zero for later
  230.         move.l    pr_CLI(a5),d1       ;Check CLI/Workbench flag
  231.         bne.s    fromCLI
  232.  
  233.         move.l    pr_StackSize(a5),d6 ;--Get Workbench stack size--
  234.         lea.l    pr_MsgPort(a5),a0   ;Wait for the message
  235.         jsrlib    WaitPort        ; the Workbench will send
  236.         lea.l    pr_MsgPort(a5),a0
  237.         jsrlib    GetMsg
  238.  
  239. fromCLI     move.l    d0,-(a7)            ;Save the message, or zero
  240. ******************************************  A5-This task D7-Stack size
  241.  
  242.         ;...your code here...
  243.  
  244. ******************************************  D7-MUST contain result code
  245. ExitToDOS:    move.l    (a7)+,d2
  246.         beq.s    notWorkbench
  247.  
  248.         jsrlib    Forbid        ;Required so we won't be unloaded by
  249.         move.l    d2,a1        ; the Workbench too soon.
  250.         jsrlib    ReplyMsg    ;Reply to the Workbench message
  251.  
  252. notWorkbench    move.l    d7,d0        ;Return result code:
  253.         rts            ; 0 = ok       10 = error
  254.         END            ; 5 = warning  20 = severe failure
  255.  
  256.  
  257.  
  258.  
  259.